package jpavlich.cardsorter.action;

import java.awt.geom.Point2D;

import fr.inria.zvtm.animation.ActionTimingHandler;
import fr.inria.zvtm.animation.Animation;
import fr.inria.zvtm.animation.Animation.Dimension;
import fr.inria.zvtm.animation.interpolation.SlowInSlowOutInterpolator;
import fr.inria.zvtm.engine.Camera;
import fr.inria.zvtm.engine.Location;
import fr.inria.zvtm.engine.View;
import fr.inria.zvtm.engine.VirtualSpaceManager;
import fr.inria.zvtm.glyphs.Glyph;

public class MoveCamera extends Action<MoveCamera> {

	SerializableLocation to;
	SerializableLocation from;
	protected String viewID;
	protected String cameraID;
	protected int duration;

	public MoveCamera(SerializableLocation to, int duration, View view, Camera camera) {
		super();
		this.to = to;
		this.from = new SerializableLocation(camera.getLocation());
		this.duration = duration;
		this.viewID = getResourceManager().getResourceID(view);
		this.cameraID = getResourceManager().getResourceID(camera);
	}

	protected void moveCameraTo(Location l) {
		Animation trans = VirtualSpaceManager.INSTANCE
				.getAnimationManager()
				.getAnimationFactory()
				.createCameraTranslation(duration, (Camera) getResourceManager().findResource(cameraID), new Point2D.Double(l.vx, l.vy), false,
						SlowInSlowOutInterpolator.getInstance(), null);

		Animation alt = VirtualSpaceManager.INSTANCE
				.getAnimationManager()
				.getAnimationFactory()
				.createCameraAltAnim(duration, (Camera) getResourceManager().findResource(cameraID), l.alt, false, SlowInSlowOutInterpolator.getInstance(),
						null);

		VirtualSpaceManager.INSTANCE.getAnimationManager().startAnimation(trans, false);
		VirtualSpaceManager.INSTANCE.getAnimationManager().startAnimation(alt, false);
	}

	@Override
	public void undo() {
		moveCameraTo(from);
	}

	@Override
	public MoveCamera clone() {
		return new MoveCamera(to, duration, (View) getResourceManager().findResource(viewID), (Camera) getResourceManager().findResource(cameraID));
	}

	@Override
	void execute() {

	}

	@Override
	public Animation createAnimation() {
		final Camera camera = (Camera) getResourceManager().findResource(cameraID);
		return VirtualSpaceManager.INSTANCE
				.getAnimationManager()
				.getAnimationFactory()
				.createAnimation((int) duration, camera, Animation.Dimension.POSITION,
		 new ActionTimingHandler() {
			private double startX = Double.MIN_VALUE;
			private double startY = Double.MIN_VALUE;
			private double startZ = Double.MIN_VALUE;
			private double endX = Double.MIN_VALUE;
			private double endY = Double.MIN_VALUE;
			private double endZ = Double.MAX_VALUE;

			@Override
			public void begin(Object subject, Animation.Dimension dim) {
				
				startX = camera.getLocation().vx;
				startY = camera.getLocation().vy;
				startZ = camera.getAltitude();
				endX = to.vx;
				endY = to.vy;
				endZ = to.alt;
			}

			@Override
			public void timingEvent(float fraction, Object subject, Animation.Dimension dim) {
				camera.moveTo(startX + fraction * (endX - startX), startY + fraction * (endY - startY));
				camera.setAltitude(startZ + fraction * (endZ - startZ));
			}
		});

	}

}
